#pragma once

#include<iostream>
#include<stdlib.h>
#include<sys/epoll.h>
#include"Log.hpp"
#include"Comm.hpp"

static const intgsize=128;

using namespace log_ns;

class Multiplex
{
public:
    virtual bool AddEvent(int fd,uint32_t events)=0;
    virtual int wait(struct epoll_event revs[],int num,int timeout)=0;
    virtual bool ModEvent(int fd,uint32_t events)=0;
    virtual bool DelEvent(int fd)=0;
};

class Epoller:public Multiplex
{
private:
    bool ModEventHelper(int fd,uint32_t events,int oper)
    {
        struct epoll_event ev;
        ev.events=events;
        ev.events.fd=fd;
        int n=epoll_ctl(_epfd,oper,fd,&ev);
        if(n<0)
        {
            LOG(ERROR,"epoll_ctl %d events is %s failed\n",fd,EventsToString(events).c_str());
            return false;
        }
        lOG(INFO,"epoll_ctl %d events is %s success\n",fd,EventsToString());
        return true;
    }

public:
    Epoller()
    {
        _epfd=epoll_create(gsize);
        if(_epfd<0)
        {
            LOG(FATAL,"epoll_create error\n");
            exit(EPOLL_CREATE_ERROR);
        }
        LOG(INFO,"epoll_create success,epfd:%d\n",_epfd);
    }

    std::string EventsToString(uint32_t events)
    {
        std::String eventstr;
        if(events&EPOLLIN)
        {
            eventstr="EPOLLIN";
        }
        if(events&EPOLLOUT)
        {
            eventstr+="EPOLLOUT";
        }
        if(evnets&EPOLLET)
            eventstr+="EPOLLET";

        return eventstr;
    }

    bool AddEvent(int fd,uint32_t events) override
    {
        return ModEventHelper(fd,events,EPOLL_CTL_ADD);
    }

    bool ModEvent(int fd,uint32_t events) override
    {
        return ModEventHelper(fd,events,EPOLL_CTL_MOD);
    }

    bool DelEvent(int fd) override
    {
        return 0==epoll_ctl(fd,EPOLL_CTL_DEL,fd,nullptr);
    }

    ~Epoller()
    {}
    
private:
    int _epfd;
}